<template>
    <div class="v-waterfall" ref="waterfallRef">
        <div class="v-waterfall-wrap" :style="waterfallWrapStyle">
            <div class="v-waterfall-item" v-for="(d, i) in waterfallData" :key="`item-${i}`">
                <div class="v-waterfall-item-wrap" :style="getWaterfallItemStyle(item)" v-for="item in d" :key="item.id">
                    <slot name="item" :item="item"></slot>
                </div>
            </div>
        </div>
    </div>
</template>
  
<script setup lang="ts">
import { CSSProperties, computed, onMounted, reactive, ref, onUnmounted, nextTick, watch } from 'vue';
import { WaterfallItem, WaterfallItems } from '../types';

const props = withDefaults(defineProps<{
    items?: WaterfallItems | any[];
    width?: number
    column?: number;
    gutter?: number; // 间距
    style?: CSSProperties;
}>(), {
    items: () => [],
    width: 400,
    gutter: 10
})
let waterfallData = ref<WaterfallItems | any[]>(props.items);
const com = reactive({ ...props });
const waterfallRef = ref<HTMLElement | null>(null);

const waterfallWrapStyle = computed(() => {
    const style: CSSProperties = {};
    return style;
})

const getWaterfallItemStyle = (item: WaterfallItem) => {
    return {
        ...com.style,
        margin: `${com.gutter}px`,
        flex: item.width ? 'unset' : '1',
        width: item.width ? `${item.width}px` : 'auto',
    } as CSSProperties;
}
onMounted(async () => {
    await nextTick();
    window.addEventListener('resize', resizeHandle)
    dispatchEvent(new Event('resize'));
})
onUnmounted(() => {
    window.removeEventListener('resize', resizeHandle)
})
let timer: any = null;
function resizeHandle() {
    clearTimeout(timer);
    timer = setTimeout(() => {
        // 总宽度
        const totalWidth = document.body.clientWidth;
        // 根据props.width计算列数
        const col = Math.floor(totalWidth / com.width) || 1;
        // 每一列放多少图片
        const num = Math.ceil(props.items.length / col);
        // 根据列数切割数组
        waterfallData.value = props.items.map((_item, index: number) => {
            if (index <= col - 2) {
                return props.items.slice(index * num, (index + 1) * num)
            }
            if (index === col - 1) {
                return props.items.slice(index * num)
            }
            return []
        });
        waterfallData.value = waterfallData.value.filter((item: any) => item.length > 0);
        // console.log('col', col);
        // console.log('num', num);
        // console.log('waterfallData', waterfallData.value);
        // console.log(getComputedStyle(waterfallRef.value).width);
    }, 200)
}
watch(props, (newProps) => {
    newProps.items = waterfallData.value;
    dispatchEvent(new Event('resize'));
})

</script>
<script lang="ts">
export default {
    name: 'VWaterfall',
}
</script>
<style scoped>
.v-waterfall {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    transition: all 0.5s ease-in-out;
}

.v-waterfall .v-waterfall-wrap {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: row;
}

.v-waterfall .v-waterfall-wrap .v-waterfall-item {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
}

.v-waterfall .v-waterfall-wrap .v-waterfall-item .v-waterfall-item-wrap {
    width: 100%;
    border-radius: 5px;
    margin: 10px;
    flex: 1;
    display: inline-flex;
    box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
}
</style>